/* The code examples copyrighted by Nokia Corporation that are included to
 * this material are licensed to you under following MIT-style License:
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <MApplication>

#include <QDateTime>
#include <QDeclarativeContext>
#include <QDeclarativeView>

#include <mkcal/extendedcalendar.h>
#include <mkcal/extendedstorage.h>
#include <kcalcoren/incidence.h>

#include "calendarmodel.h"
#include "calendarexample.h"

static const int RecurrenceTypeMap[] = {0, KCalCore::RecurrenceRule::rDaily, KCalCore::RecurrenceRule::rWeekly, KCalCore::RecurrenceRule::rMonthly, KCalCore::RecurrenceRule::rYearly };

CalendarExample::CalendarExample(QDeclarativeContext *context)
{
    calendar = mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(KDateTime::Spec::LocalZone()));
    storage = calendar->defaultStorage(calendar);
    calendarModel = new CalendarModel(this, calendar, storage, QDateTime::currentDateTime().date());


    context->setContextProperty("CalendarModel", calendarModel);
    context->setContextProperty("CalendarExample", this);

    // Populate notebook list. If no notebooks exist, create one.
    mKCal::Notebook::Ptr notebook;
    mKCal::Notebook::List notebooks = storage->notebooks();

    if(notebooks.size()==0) {
        notebook = mKCal::Notebook::Ptr(new mKCal::Notebook(QString(), "Test notebook"));
        storage->addNotebook(notebook);
        notebooks = storage->notebooks();
        storage->save();
    }

    foreach(notebook, notebooks) {
        notebookList.append(notebook->name());
    }
}


CalendarExample::~CalendarExample()
{
}


// Add event based on user entered data
bool CalendarExample::AddEvent(const QString &summary, const QString &description, const QString &location, const QString &eventDateString, const QString &eventEndDateString, const QString &startTimeString, const QString &endTimeString, const int &recurrenceRule)
{
    const QDate date     = QDate::fromString(eventDateString, Qt::ISODate);
    const QTime startTime= QTime::fromString(startTimeString, Qt::ISODate);
    const QTime endTime  = QTime::fromString(endTimeString,   Qt::ISODate);
    const QDate endDate = QDate::fromString(eventEndDateString, Qt::ISODate);


    // Make sure given information is valid
    if (date.isValid() && endDate.isValid() && startTime.isValid() && endTime.isValid()) {
        KCalCore::Event::Ptr event = KCalCore::Event::Ptr(new KCalCore::Event());
        event->setDtStart(KDateTime(QDateTime(date, startTime)));
        event->setDtEnd(KDateTime(QDateTime(date, endTime)));
        event->setSummary(summary);
        event->setDescription(description);
        event->setLocation(location);

        if (recurrenceRule > 0) {

            // Event is recurring, set rule accordingly
            KCalCore::RecurrenceRule::PeriodType periodType;

            periodType = static_cast<KCalCore::RecurrenceRule::PeriodType>(RecurrenceTypeMap[recurrenceRule]);

            KCalCore::RecurrenceRule *recurrenceRule = new KCalCore::RecurrenceRule();
            recurrenceRule->setStartDt(KDateTime(date));
            recurrenceRule->setEndDt(KDateTime(endDate));
            recurrenceRule->setRecurrenceType(periodType);
            event->recurrence()->addRRule(recurrenceRule);
        }

        mKCal::Notebook::List notebooks = storage->notebooks();
        mKCal::Notebook::Ptr notebook;
        if (notebooks.size()>0) {
            for (int i = 0; i < notebooks.size(); i++)
            {
                notebook=notebooks.at(i);
                QString notebookUid = notebook->uid();
                //Exit loop when first valid notebook found and event saved
                if (storage->isValidNotebook(notebookUid)) {
                    if(calendar->addEvent(event, notebookUid)) {
                        storage->save();
                        calendarModel->eventAdded(event);
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

bool CalendarExample::RemoveEvent(int row)
{
    if(row < 0)
        return false;

    return calendarModel->removeEvent(row);
}

void CalendarExample::SetDate(const QString &dateString)
{
    const QDate date=QDate::fromString(dateString, Qt::ISODate);
    calendarModel->dateChanged(date);
}

int main(int argc, char *argv[])
{
    MApplication app(argc, argv);
    QDeclarativeView view;

    CalendarExample calendarExample(view.rootContext());

    view.setSource(QUrl("qrc:/calendar-qml-example.qml"));
    view.showFullScreen();

    return app.exec();
}
